package com.icangya.Utils;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate5.HibernateCallback;
import org.springframework.orm.hibernate5.HibernateTemplate;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by 王小红 on 2017/5/13.
 */
public class SQLUtilt {
    // 定义一个私有构造方法
    private SQLUtilt() {

    }

    //定义一个静态私有变量(不初始化，不使用final关键字，使用volatile保证了多线程访问时instance变量的可见性，避免了instance初始化时其他变量属性还没赋值完时，被另外线程调用)
    private static volatile SQLUtilt instance;

    //定义一个共有的静态方法，返回该类型实例
    public static SQLUtilt getIstance() {
        // 对象实例化时与否判断（不使用同步代码块，instance不等于null时，直接返回对象，提高运行效率）
        if (instance == null) {
            //同步代码块（对象未初始化时，使用同步代码块，保证多线程访问时对象在第一次创建后，不再重复被创建）
            synchronized (SQLUtilt.class) {
                //未初始化，则初始instance变量
                if (instance == null) {
                    instance = new SQLUtilt();
                }
            }
        }
        return instance;
    }

    /**
     * 做数据库分页
     *
     * @param template  数据库
     * @param HQL
     * @param total     总数据量
     * @param startpage 开始页码
     * @param row       一页多少数据
     * @param values    参数 请与HQL一一匹配
     * @return .0为数据 .1为总页码 02为当前页码
     */
    public List doPage(HibernateTemplate template, final String HQL, final long total, final int startpage, final int
            row, final Object... values) {
        return template.execute(new HibernateCallback<List>() {
            @Override
            public List doInHibernate(Session session) throws HibernateException {
                int inPage = startpage;
                Query query = session.createQuery(HQL);
                if (values != null)
                    for (int i = 0; i < values.length; i++) {
                        query.setParameter(i, values[i]);
                    }
                int totalPage;
                if (total % row == 0)
                    totalPage = Math.toIntExact(total / row);
                else
                    totalPage = Math.toIntExact(total / row) + 1;
                if (inPage <= 0) //负页码
                    inPage = 1;
                if (inPage >= totalPage)//超出页码
                    inPage = totalPage;
                query.setFirstResult((inPage - 1) * row);
                query.setMaxResults(row);
                List list =  new ArrayList();
                list.add(query.list());//数据
                list.add(totalPage);//总页码
                list.add(inPage);//当前页码
                return list;
            }
        });
    }


}
